

#include  "usart.h"
#include <stdio.h>
#include <stdarg.h>//sprintf的家
#include <math.h>


//定义缓存区的数组

char Serial_RxPacket[100];//最大//单条指令最长不能超过100//缓存数组//中断函数依次写入//主函数中依次读出
 //数据包之间会混在一起//读出数据可能是既是上一个数据包又是下一个数据包//
uint8_t usart_Rxflag;


void usart_init(void)
{
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//TX输出引脚复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//发送端
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//RX上拉输入                                   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//接受端
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
	//RX输入引脚//浮空或上拉//串口通信空闲状态高电平不能下拉
	
	
	USART_InitTypeDef a;
	a.USART_BaudRate=9600;//波特率//自动算好DIV=72M/9600/16
	a.USART_WordLength=USART_WordLength_8b;//字长8位
	a.USART_StopBits=USART_StopBits_1;//1位停止位
	a.USART_Parity=USART_Parity_No;//不校验
	a.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//发送模式
	a.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件流控
	USART_Init(USART3,&a);
	
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//开启RXNE标志位到NVIC的输出
	
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	
	
	
//	NVIC_InitTypeDef b;
//	b.NVIC_IRQChannel=USART3_IRQn;//
//	b.NVIC_IRQChannelCmd=ENABLE;
//	b.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
//	b.NVIC_IRQChannelSubPriority=1;//
//	NVIC_Init(&b);
	
	USART_Cmd(USART3,ENABLE);//串口使能
}

void  usart_sendbit(uint8_t  byte)
{
		USART_SendData(USART3,byte);
	//先给DATA再把无关变量高位清零，赋值给DR寄存器，写入DR，数据最终通向TDR，
	//再给发送移位寄存器，最后一位一位的把数据移出TX引脚完成数据发送
	while  (USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET);
	//等待TEX（发送寄存器空标志位）置一
	//下一次发送数据时自动清零
	
}
void usart_senda(uint8_t *a,uint16_t l)//指针类型指向待发送数组的首地址//数组无法判断是否结束需要传递一个l进来
{
	uint16_t i;
	for(i=0;i<l;i++)
	{
		usart_sendbit(a[i]);//依次取出数组的每一项
		
		
	}
	
}

void usart_sendstring(char *string)
{
	uint16_t i;
	for(i=0;string[i]!='\0';i++)//空字符的转义字符位\0
	{
		usart_sendbit(string[i]);//依次取出数组的每一项	
	}
}


uint32_t usart_pow(uint32_t X, uint32_t Y)
{
	uint32_t R=1;
	while(Y--)//定义X的Y次方
	{
		R=R*X;
	}
	return R;
	
}



void usart_sendnum(uint32_t n,uint8_t l)
{
	uint16_t i;
	for(i=0;i<l;i++)//空字符的转义字符位\0
	{
		usart_sendbit(n/usart_pow(10,l-i-1)%10+'0');//十进制从高位到底位依次传递//	
	}
}

int fputc(int ch,FILE *f)//fputc函数的原型
{
	usart_sendbit(ch);//重定向fputc到串口
	
	return ch;//printf打印时不断调用fputc函数打印
	
	
}



//对sprintf进行封装（printf可变参数）
void usart_printf(char *f,...)//f用来接受格式化字符串//...用来接受可变参数列表
{
	char string[100];
	va_list arg;//定义一个列表参数变量//va_list是类型名//arg为变量
	va_start(arg,f);//从f位置开始接受参数表，放在arg中
	vsprintf(string,f,arg);//打印位置是string//格式化字符串是f//参数表是arg//
	//sprintf只能接受直接写的参数//对于此类封装格式要用vsprintf
	va_end(arg);//释放参数表
	usart_sendstring(string);//发送string
	
}

void usart_sendsignednum(int32_t n,uint8_t l)
{
	uint32_t m;
	if(n>=0)
	{
		usart_sendstring("+");
		n=(uint32_t)n;
		usart_sendnum(n,l);
	}
	else if(n<0)
	{
		usart_sendstring("-");
		
		m=-n;
		usart_sendnum(m,l);
	}
		
	
	
	
}





uint8_t usart_getRxflag(void)//实现读后自动清除
{
	if(usart_Rxflag==1)
	{
		usart_Rxflag=0;
		return 1;
	}
	return 0;
	
}








//可变包长含包头包尾
//接受数据包并存储到RxP中
void USART3_IRQHandler(void)
{
	//静态变量
	static uint8_t Rxstate=0;//类似于全局变量，函数进入仅初始化一次零，函数退出后数据仍然有效
	static uint8_t pRxP=0;
	if(USART_GetFlagStatus(USART3,USART_IT_RXNE)==SET)
	{
		uint8_t Rxdata=USART_ReceiveData(USART3);//获取数据
		
		
		//状态机
		if(Rxstate==0)//等待包头的程序//
		{
			if(Rxdata=='@' )//收到包头//
			{
				Rxstate=1;//转移状态
				pRxP=0;//提前清零
			}
			
		}
		
		else if(Rxstate==1)//接受数据的程序//避免连续两个if同时成立
		{
			//载荷字符数量不确定每次接受之前判断是不是包尾
			if(Rxdata==' ')//收到第一个包尾
			{
				Rxstate=2;
			}
			else
			{
				Serial_RxPacket[pRxP] = Rxdata;//将获取到的数据放在定义的数组中
				pRxP++;//移位
			}
		}
		else if(Rxstate==2)//等待包尾的程序
		{
			if(Rxdata=='.')//收到第二个包尾//
			{
				Rxstate= 0;//转移状态
				Serial_RxPacket[pRxP]='\0';//写入字符数组的下一位置结束标志位
				usart_Rxflag = 1;//表示收到数据
			}
			
		}
			
		USART_ClearITPendingBit(USART3,USART_IT_RXNE);
	}
	
	
}

uint16_t usart_123ascll(char a[],uint32_t diji)
{
	uint32_t i=0,s=0;
	
	for(i=1;i<=diji;i++)
	{
		
		s=s*10+a[i-1]-48;	
	}
	return s;

}

















